using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System;
using System.Collections;
using System.Web.UI;
using System.IO;
using System.Configuration;
using System.Threading;
using Microsoft.SharePoint.Utilities;

namespace NikCodes.SharePoint.ClientSide
{
    public class Settings : LayoutsPageBase
    {
        #region Members

        protected InputFormSection JQuerySection;
        protected InputFormSection JQueryUISection;
        protected InputFormSection PrototypeSection;
        protected InputFormSection ScriptaculousSection;
        protected CheckBox JQueryCheckbox;
        protected LinkButton JQueryDemoLink;
        protected Label JQueryWarning;
        protected CheckBox JQueryUICheckbox;
        protected Label JQueryUIWarning;
        protected LinkButton JQueryUIDemoLink;
        protected DropDownList JQueryUIThemes;
        protected CheckBox PrototypeCheckbox;
        protected Label PrototypeWarning;
        protected CheckBox ScriptaculousCheckbox;
        protected Label ScriptaculousWarning;
        protected CheckBox ScriptaculousBuilderCheckbox;
        protected CheckBox ScriptaculousEffectsCheckbox;
        protected CheckBox ScriptaculousDragDropCheckbox;
        protected CheckBox ScriptaculousControlsCheckbox;
        protected CheckBox ScriptaculousSliderCheckbox;
        protected CheckBox ScriptaculousSoundCheckbox;
        protected CheckBox ScriptaculousUnitTestCheckbox;
        protected LinkButton ScriptaculousDemoLink;
        protected CheckBox ExtCheckbox;
        protected LinkButton ExtDemoLink;
        protected Button OkButton;

        private SPPropertyBag _webProperties;

        #endregion

        #region Properties

        public SPPropertyBag WebProperties
        {
            get { return _webProperties ?? (_webProperties = Web.Properties); }
            set { _webProperties = value; }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        public Settings()
        {
            // We add OnInit the event Init
            Init += OnInit;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Occurs when the control is initialized.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnInit(object sender, System.EventArgs e)
        {
            // We add OnLoad to the Load event
            Load += OnLoad;
        }

        /// <summary>
        /// Occurs when the control is loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnLoad(object sender, System.EventArgs e)
        {
            // We set handler for OnClick event
            OkButton.Click += OnOkClick;
            JQueryDemoLink.Click += OnJQueryDemoLinkClick;
            JQueryUIDemoLink.Click += OnJQueryUIDemoLinkClick;
            ScriptaculousDemoLink.Click += OnScriptaculousDemoLinkClick;
            ExtDemoLink.Click += OnExtDemoLinkClick;

            // We set handler for CheckBox changes event
            JQueryCheckbox.CheckedChanged += OnCheckChanged;
            PrototypeCheckbox.CheckedChanged += OnCheckChanged;
            ScriptaculousCheckbox.CheckedChanged += OnCheckChanged;

            // We setup the postback
            JQueryCheckbox.AutoPostBack = JQueryUICheckbox.AutoPostBack = PrototypeCheckbox.AutoPostBack = ScriptaculousCheckbox.AutoPostBack = ExtCheckbox.AutoPostBack = true;
            
            // The form is not posted back by the user
            if (!IsPostBack) 
            {
                // We build the themes dropdown list
                string[] themes = Utilities.GetAllJQueryUIThemes();
                foreach (string theme in themes)
                {
                    JQueryUIThemes.Items.Add(theme);
                }

                // We set the checkbox accordingly with the properties stored in the propertie bags
                JQueryCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "JQuery");
                PrototypeCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "Prototype");
                JQueryUICheckbox.Checked = Utilities.IsPropertySet(WebProperties, "JQueryUI");
                JQueryUIThemes.SelectedValue = Utilities.GetProperty(WebProperties, "JQueryUITheme");
                ScriptaculousCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "Scriptaculous");
                ScriptaculousBuilderCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "ScriptaculousBuilder");
                ScriptaculousEffectsCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "ScriptaculousEffects");
                ScriptaculousDragDropCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "ScriptaculousDragDrop");
                ScriptaculousControlsCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "ScriptaculousControls");
                ScriptaculousSliderCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "ScriptaculousSlider");
                ScriptaculousSoundCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "ScriptaculousSound");
                ScriptaculousUnitTestCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "ScriptaculousUnitTest");
                ExtCheckbox.Checked = Utilities.IsPropertySet(WebProperties, "Ext");
            }

            // We set the checkboxes and hidde regions if necessary
            SetCheckBoxes();
        }

        /// <summary>
        /// Occurs when the users clicks on the OK button to validate the page
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnOkClick(object sender, EventArgs e)
        {
            // We save the properties
            SaveProperties();
            WebProperties.Update();

            SPUtility.Redirect("settings.aspx", SPRedirectFlags.RelativeToLayoutsPage, Context);
        }
        
        protected void OnJQueryDemoLinkClick(object sender, EventArgs e)
        {
            SaveProperties();
            SPUtility.Redirect("ClientSide/jquery/DemoJQuery.aspx", SPRedirectFlags.RelativeToLayoutsPage, Context);
        }

        protected void OnJQueryUIDemoLinkClick(object sender, EventArgs e)
        {
            SaveProperties();
            SPUtility.Redirect("ClientSide/jqueryui/DemoJQueryUI.aspx", SPRedirectFlags.RelativeToLayoutsPage, Context);
        }

        protected void OnScriptaculousDemoLinkClick(object sender, EventArgs e)
        {
            SaveProperties();
            SPUtility.Redirect("ClientSide/scriptaculous/DemoScriptaculous.aspx", SPRedirectFlags.RelativeToLayoutsPage, Context);
        }

        protected void OnExtDemoLinkClick(object sender, EventArgs e)
        {
            SaveProperties();
            SPUtility.Redirect("ClientSide/ext/DemoExt.aspx", SPRedirectFlags.RelativeToLayoutsPage, Context);
        }

        /// <summary>
        /// Saves all the properties into propertie bags
        /// </summary>
        private void SaveProperties()
        {
            // We save the properties
            SaveProperty("JQuery", IsChecked(JQueryCheckbox).ToString());
            SaveProperty("JQueryUI", IsChecked(JQueryUICheckbox).ToString());
            SaveProperty("JQueryUITheme", JQueryUIThemes.SelectedValue);
            SaveProperty("Prototype", IsChecked(PrototypeCheckbox).ToString());
            SaveProperty("Scriptaculous", IsChecked(ScriptaculousCheckbox).ToString());
            SaveProperty("ScriptaculousBuilder", IsChecked(ScriptaculousBuilderCheckbox).ToString());
            SaveProperty("ScriptaculousControls", IsChecked(ScriptaculousControlsCheckbox).ToString());
            SaveProperty("ScriptaculousDragDrop", IsChecked(ScriptaculousDragDropCheckbox).ToString());
            SaveProperty("ScriptaculousEffects", IsChecked(ScriptaculousEffectsCheckbox).ToString());
            SaveProperty("ScriptaculousSlider", IsChecked(ScriptaculousSliderCheckbox).ToString());
            SaveProperty("ScriptaculousSound", IsChecked(ScriptaculousSoundCheckbox).ToString());
            SaveProperty("ScriptaculousUnitTest", IsChecked(ScriptaculousUnitTestCheckbox).ToString());
            SaveProperty("Ext", IsChecked(ExtCheckbox).ToString());

            WebProperties.Update();
        }

        /// <summary>
        /// Occurs when a check box changes. Only occurs when AutoPostBack is true (seen OnLoad method)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnCheckChanged(object sender, EventArgs e)
        {
            SetCheckBoxes();
        }

        /// <summary>
        /// Tests if a check box is checked and enabled or not
        /// </summary>
        /// <param name="checkbox">The check box to analyze</param>
        /// <returns>True if checked and enabled. False if unchecked or disabled.</returns>
        private static bool IsChecked(CheckBox checkbox)
        {
            return (checkbox.Checked && checkbox.Enabled);
        }

        /// <summary>
        /// Set checkboxed values and visibility of sections
        /// </summary>
        private void SetCheckBoxes()
        {
            // We disable JQuery if Prototype is used and display a warning
            JQueryCheckbox.Enabled = !PrototypeCheckbox.Checked;
            if (!JQueryCheckbox.Enabled) JQueryCheckbox.Checked = false;
            JQueryWarning.Visible = PrototypeCheckbox.Checked;
            JQueryDemoLink.Visible = JQueryCheckbox.Checked;

            // JQueryUI is enabled only if jQuery is checked
            JQueryUICheckbox.Enabled = JQueryCheckbox.Checked;
            if (!JQueryUICheckbox.Enabled) JQueryUICheckbox.Checked = false;
            JQueryUIThemes.Enabled = JQueryCheckbox.Checked;
            JQueryUIWarning.Visible = !JQueryCheckbox.Checked;
            JQueryUIDemoLink.Visible = JQueryUICheckbox.Checked;

            // We disable Prototype if jQuery is used and display a warning
            PrototypeCheckbox.Enabled = !JQueryCheckbox.Checked;
            if (!PrototypeCheckbox.Enabled) PrototypeCheckbox.Checked = false;
            PrototypeWarning.Visible = JQueryCheckbox.Checked;

            //Scriptaculous is enabled only if proto is checked
            ScriptaculousCheckbox.Enabled = PrototypeCheckbox.Checked;
            ScriptaculousWarning.Visible = !PrototypeCheckbox.Checked;
            ScriptaculousDemoLink.Visible = ScriptaculousCheckbox.Checked;

            // We enable sub scriptaculous if scriptaculous is checked
            ScriptaculousBuilderCheckbox.Enabled = IsChecked(ScriptaculousCheckbox);
            ScriptaculousControlsCheckbox.Enabled = IsChecked(ScriptaculousCheckbox);
            ScriptaculousDragDropCheckbox.Enabled = IsChecked(ScriptaculousCheckbox);
            ScriptaculousEffectsCheckbox.Enabled = IsChecked(ScriptaculousCheckbox);
            ScriptaculousSliderCheckbox.Enabled = IsChecked(ScriptaculousCheckbox);
            ScriptaculousSoundCheckbox.Enabled = IsChecked(ScriptaculousCheckbox);
            ScriptaculousUnitTestCheckbox.Enabled = IsChecked(ScriptaculousCheckbox);
            if (!PrototypeCheckbox.Checked || !ScriptaculousCheckbox.Checked)
            {
                ScriptaculousCheckbox.Checked = false;
                ScriptaculousBuilderCheckbox.Checked = false;
                ScriptaculousControlsCheckbox.Checked = false;
                ScriptaculousDragDropCheckbox.Checked = false;
                ScriptaculousEffectsCheckbox.Checked = false;
                ScriptaculousSliderCheckbox.Checked = false;
                ScriptaculousSoundCheckbox.Checked = false;
                ScriptaculousUnitTestCheckbox.Checked = false;
            }

            // Ext
            ExtDemoLink.Visible = ExtCheckbox.Checked;
        }

        /// <summary>
        /// Saves the properties into the property bag
        /// </summary>
        /// <param name="key">The key to save</param>
        /// <param name="value">The value to save</param>
        private void SaveProperty(string key, string value) 
        {
            // We add the prefix code to the key
            key = Utilities.PrefixCode + key;

            // We remove any existing propertie that has the same key
            if (WebProperties.ContainsKey(key))
                WebProperties.Remove(key);

            // We can safely add the property
            WebProperties.Add(key, value);
        }

        /// <summary>
        /// Always returns true since this page requires to be Admin of the site
        /// </summary>
        protected override bool RequireSiteAdministrator
        {
            get { return true; }
        }

        #endregion
    }
}
